package com.testcase.viewsen;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;

import org.htmlparser.Parser;
import org.htmlparser.filters.CssSelectorNodeFilter;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.tags.ImageTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.sensetecnic.client.SenseTecnicClient;
import com.sensetecnic.client.SenseTecnicException;
import com.testcase.R;
import com.testcase.SensorListTableView;
import com.testcase.SensorNames;
import com.testcase.visualization.VisualInterfaceActivity;

public class SensorDescActivity extends Activity {

	private List<String> senList;
	private List<String> imageLinks;
	private int id;
	private static final int DIALOG_CHOICE = 0;
	private SensorNames bothTitles;
	
	//Android set Visibility int for Progress Bar
	private static final int GONE = 8;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//A request required for progress bars
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.senspage);
		setProgressBarVisibility(true);
		setProgressBarIndeterminateVisibility(true);
		
		@SuppressWarnings("unchecked")
		HashMap<String, List<String>> data = (HashMap<String, List<String>>) getIntent().getSerializableExtra("sensorList");
		senList = data.get("senList");
		
		//Get the title of the Sensor Clicked
		String sensTitle = getIntent().getStringExtra("title");
		TextView tvTitle = (TextView) findViewById(R.id.sensTitle);
		tvTitle.setText(sensTitle);
		
		//Using negative one as it is a number that should never be sent from another activity
		//Don't do anything to protect from negative one though
		id = (int) getIntent().getIntExtra("index", -1);
		//Create a SensorNames class
		bothTitles = new SensorNames(senList.get(id));
		//Use AsyncTask to get the description and static map
		AsyncTask<Void, Void, String> task = new GetDescAndImageTask().execute();
		
		Button but = (Button) findViewById(R.id.sensBut);
		but.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				showDialog(DIALOG_CHOICE);
			}
		});
	}
	
	//An AsyncTask used to not slowdown the Description page from loading
	private class GetDescAndImageTask extends AsyncTask<Void, Void, String> {
	     protected void onPostExecute(String description) {
	    	 ProgressBar pb = (ProgressBar) findViewById(R.id.descAndImageProgress);
	    	 setProgressBarVisibility(false);
	    	 pb.setVisibility(GONE);
	    	 setProgressBarIndeterminateVisibility(false);
	    	 TextView tvDesc = (TextView) findViewById(R.id.sensDesc);
	 		tvDesc.setText(description);
	 		
	 		//Below draws the static map from the parsed link
	 		ImageView staticMap = (ImageView) findViewById(R.id.staticMap);
	 		InputStream is;
	 		try {
	 			is = (InputStream) new URL(imageLinks.get(id)).getContent();
	 			Drawable draw = Drawable.createFromStream(is, bothTitles.getFullTitle());
	 			staticMap.setImageDrawable(draw);
	 		} catch (MalformedURLException e) {
	 			// Do Nothing
	 		} catch (IOException e) {
	 			// Do Nothing
	 		}
	     }

		@Override
		protected String doInBackground(Void... params) {
			//Get the static map by parsing Sense Tecnic Gallery
			//Get the description by parsing Sense Tecnic sensor page
			String description = null;
			try {
				imageLinks = imageLinksParse();
				description = parseDesc(bothTitles.getTitle());
			} catch(SenseTecnicException e) {
				TextView tv = (TextView) findViewById(R.id.sensDesc);
				if(e.toString().contains("Unauthorized")) {
					tv.setText("Your username/password combination is incorrect");
				} else {
					tv.setText(e.toString());
				}
			} catch(ParserException e) {
				TextView tv = (TextView) findViewById(R.id.sensDesc);
				tv.setText(e.toString());
			}
			return description;
		}
	 }
	
	@Override
    protected Dialog onCreateDialog(int iden) {
		switch (iden) {
        case DIALOG_CHOICE:
        	return new AlertDialog.Builder(this)
            .setTitle(R.string.pickView)
            .setItems(R.array.viewList, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                	//Knowing the item lists the following can be done
                	switch(whichButton) {
                	//Start Table Activity
                	case 0:
                		Intent intent = new Intent(getApplicationContext(), SensorListTableView.class);
                		Hashtable<String, List<String>> ht = new Hashtable<String, List<String>>();
                  	    ht.put("senList", senList);
                  	    intent.putExtra("index", id);
                  	    intent.putExtra("sensorList", ht);
                  	    startActivity(intent);
                  	    break;
                  	//Start Google Visualisation
                	case 1:
                		intent = new Intent(getApplicationContext(), VisualInterfaceActivity.class);
                		ht = new Hashtable<String, List<String>>();
                  	    ht.put("senList", senList);
                  	    intent.putExtra("index", id);
                  	    intent.putExtra("sensorList", ht);
                  	    startActivity(intent);
                  	    break;
                  	//Start Google Maps
                	case 2:
                		Uri uri1 = Uri.parse("geo:0,0?q=http://demo.sensetecnic.com/SenseTecnic/api/sensors/" + bothTitles.getTitle() + "/data?out=kml");
                		Intent mapIntent = new Intent(Intent.ACTION_VIEW, uri1);
                		mapIntent.setData(uri1); 
                		startActivity(Intent.createChooser(mapIntent, bothTitles.getFullTitle()));
                  	    break;
                	}
                }
            })
           .create();
		}
		return null;
	}
	
	//This parses the description using a similar technique as SensorListClick
	public String parseDesc(String sensName) throws SenseTecnicException, ParserException {
		SenseTecnicClient client = new SenseTecnicClient();
    	client.setStsBaseUrl("http://demo.sensetecnic.com/SenseTecnic/spring/sensors/");
    	
    	SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
    	Resources reso = getResources();
    	String user = pref.getString(reso.getString(R.string.stsUsernameKey), null);
    	String pass = pref.getString(reso.getString(R.string.stsPasswordKey), null);
    	String extenstion = sensName + "/monitor";
    	
    	String body = client.getHtml(user, pass, extenstion);
    	
    	Parser parser = new Parser(body);
    	CssSelectorNodeFilter cssFilter = 
    	    new CssSelectorNodeFilter("DIV.sensor-desc");
    	NodeList nodes = parser.parse(cssFilter);
    	
    	String desc = null;
    	if(nodes.elementAt(0).getFirstChild() != null) {
    		desc = (nodes.elementAt(0).getFirstChild().toPlainTextString()).trim();
    	}
    	else {
    		desc = "Sorry, there is no description for this Sensor";
    	}
    
        return desc;
	}
	
	//Parses img tags using a similar technique as SensorListClick
	public List<String> imageLinksParse() throws SenseTecnicException, ParserException {
		List<String> tmpList = new ArrayList<String>();
		SenseTecnicClient client = new SenseTecnicClient();
    	client.setStsBaseUrl("http://demo.sensetecnic.com/SenseTecnic");
    	
    	SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
    	Resources reso = getResources();
    	String user = pref.getString(reso.getString(R.string.stsUsernameKey), null);
    	String pass = pref.getString(reso.getString(R.string.stsPasswordKey), null);

    	String body = client.getHtml(user, pass, "/spring/sensors/");
    	
    	Parser parser = new Parser(body);
    	NodeList nodes = parser.parse(new NodeClassFilter (ImageTag.class));
    	
    	//Start at 1 because of the Sense Tecnic Logo is located at 0
    	for(int i = 1; i < nodes.size(); i++) {
    		ImageTag extracted = (ImageTag)nodes.elementAt(i);
    		tmpList.add(extracted.getImageURL());
    	}
        
        return tmpList;
	}
}
